﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ApplLogic.Server
{
    public enum eMethodExecutionResult
    {
        Ok,
        Exception
    }

    public class MethodExecuter
    {
        private string m_MethodToExecute;
        private object[] m_InParams;
        private object m_ReturnValue;
        private bool m_HasReturnValue;
        private MethodExecutionResult m_Result;
        private static object m_Lock = new object();


        public MethodExecuter(string methodToExecute, object[] Inparams, bool hasReturnValue)
        {
            m_MethodToExecute = methodToExecute;
            m_InParams = Inparams;
            m_ReturnValue = null;
            m_HasReturnValue = hasReturnValue;
            m_Result = new MethodExecutionResult();
        }

        public Exception GetException()
        {
            return m_Result.Exception;
        }

        public eMethodExecutionResult GetResultOfMethodExecution()
        {
            return m_Result.Result;
        }

        public void ExecuteMethod(Type objectType, object target)
        {
            lock (m_Lock)
            {
                try
                {
                    if (!m_HasReturnValue)
                    {
                        objectType.InvokeMember(m_MethodToExecute,
                                                BindingFlags.InvokeMethod | BindingFlags.Instance |
                                                BindingFlags.Public,
                                                null, target, m_InParams);
                    }
                    else
                    {
                        m_ReturnValue = objectType.InvokeMember(m_MethodToExecute,
                                                                BindingFlags.InvokeMethod | BindingFlags.Instance |
                                                                BindingFlags.Public,
                                                                null, target, m_InParams);
                    }
                    m_Result.Result = eMethodExecutionResult.Ok;
                }
                catch (Exception e)
                {
                    m_Result.Exception = e;
                    m_Result.Result = eMethodExecutionResult.Exception;
                }
            }

        }

        public bool IsExecutedOk()
        {
            return m_Result.Result == eMethodExecutionResult.Ok;
        }

        public bool HasReturnValue 
        {
            get { return m_HasReturnValue; } 
        }

        public object ReturnValue
        {
            get { return m_ReturnValue; }
        }

        public string MethodToExecute
        {
            get { return m_MethodToExecute; }
        }




        private class MethodExecutionResult
        {
            private eMethodExecutionResult m_Result;
            private Exception m_Exception;

            public MethodExecutionResult()
            {
                m_Result = eMethodExecutionResult.Ok;
                m_Exception = null;
            }

            public eMethodExecutionResult Result
            {
                get { return m_Result; }
                set { m_Result = value; }
            }

            public Exception Exception
            {
                get { return m_Exception; }
                set { m_Exception = value; }
            }
        }

    }
}
